/*
 * @Author: Jiarun
 * @Date: 2021-06-05 11:08:45
 * @LastEditors: Jiarun
 * @LastEditTime: 2021-06-08 08:25:40
 * @Description: 
 */
#include "es_exti.h"
#include <math.h>

/**
 * @description: 外部中断初始化
 * @param {GPIO_TypeDef*} GPIOx	GPIO
 * @param {uint16_t} GPIO_Pin	GPIO管脚
 * @param {EXTITrigger_TypeDef} EXTI_Trigger 中断触发方式
 * @param {uint8_t} Preemption	抢占优先级
 * @param {uint8_t} Sub			响应优先级
 * @return {*}
 * @Sample exti_init(GPIOA, GPIO_Pin_0, EXTI_Trigger_Falling, 2, 2);
 */
void exti_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, EXTITrigger_TypeDef EXTI_Trigger, uint8_t Preemption, uint8_t Sub)
{
	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;
	GPIOMode_TypeDef GPIO_Mode;
	uint8_t IRQChannel, PinSource;
	
	if(EXTI_Trigger_Rising == EXTI_Trigger)
		GPIO_Mode = GPIO_Mode_IPD;
	else if(EXTI_Trigger_Falling == EXTI_Trigger)
		GPIO_Mode = GPIO_Mode_IPU;
	else
		GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio_init(GPIOx, GPIO_Pin, GPIO_Mode);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//开启复用时钟
	
	PinSource = log(GPIO_Pin)/log(2);
	GPIO_EXTILineConfig( (( (uint32_t)GPIOx - APB2PERIPH_BASE) >> 10) - 2, PinSource);
	
	EXTI_InitStructure.EXTI_Line = GPIO_Pin;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	
	if(PinSource < GPIO_PinSource5)
		IRQChannel = PinSource + 6;
	else if(PinSource < GPIO_PinSource10)
		IRQChannel = EXTI9_5_IRQn;
	else
		IRQChannel = EXTI15_10_IRQn;
	
	NVIC_InitStructure.NVIC_IRQChannel = IRQChannel;					//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Preemption;	//抢占优先级 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = Sub;				//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						//中断使能
	NVIC_Init(&NVIC_InitStructure); 
}
